//
//  JWDrawables.m
//  KotH
//
//  Created by James Weatherley on 16/08/2008.
//  Copyright 2008 James Weatherley. All rights reserved.
//

#import "../koth.h"
#include "../wolfiphone.h"


static JWManagers* sharedManagers = nil;


@implementation JWManagers

@synthesize view;


-(id)init
{
	self = [super init];
	
	view = nil;
	selectedItem = nil;
	managers = [[NSMutableDictionary alloc] init];
	//[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(glPick:) name:@"net.weatherley.glPick" object:nil];
	
	return self;
}

-(void)dealloc
{
	[super dealloc];
	[managers release];
}

+(JWManagers*)sharedManager
{
    @synchronized(self) {
        if (sharedManagers == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedManagers;
}

+(id)allocWithZone:(NSZone*)zone
{
    @synchronized(self) {
        if (sharedManagers == nil) {
            sharedManagers = [super allocWithZone:zone];
            return sharedManagers;  // assignment and return on first allocation
        }
    }
    return nil; //on subsequent allocation attempts return nil
}

-(id)copyWithZone:(NSZone*)zone
{
    return self;
}

-(id)retain
{
    return self;
}

-(unsigned)retainCount
{
    return UINT_MAX;  //denotes an object that cannot be released
}

-(void)release
{
    //do nothing
}

-(id)autorelease
{
    return self;
}

/*
-(void)addManager:(NSObject<JWManager>*)manager withName:(NSString*)name
{
	[managers setObject:manager forKey:name];
}

-(NSObject<JWManager>*)managerWithName:(NSString*)name
{
	return [managers objectForKey:name];
}
*/
-(void)addManager:(NSObject<JWManager>*)manager
{
	[managers setObject:manager forKey:NSStringFromClass([manager class])];

}

-(NSObject<JWManager>*)managerOfClass:(Class)class_
{
	return [managers objectForKey:NSStringFromClass(class_)];
}

-(NSDictionary*)managers
{
	return managers;
}

-(void)removeAllManagers
{
	[managers removeAllObjects];
}

#pragma mark Selection
-(NSObject<JWEntity>*)selectedItem
{
	return selectedItem;
}

-(void)clearSelectedItem
{
	selectedItem = nil;
}

-(JWSquare*)selectedSquare
{
	JWSquare* square = nil;
	if([selectedItem class] == [JWSquare class]) {
		square = (JWSquare*)selectedItem;
	}
	
	return square;
}
/*
#pragma mark Notification Handlers
-(void)glPick:(NSNotification*)notification
{
	[selectedItem setSelected:NO];
	selectedItem = nil;
	
	NSDictionary* pickInfo = [notification object];
	GLint hits = [[pickInfo objectForKey:@"hits"] intValue];
	GLint* pickBuffer = [[pickInfo objectForKey:@"pickBuffer"] pointerValue];
	
	if(hits > 0) {
		JWLandscapeDrawable* landcapeDrawable = [managers objectForKey:@"landscape"];
		JWLandscape* landscape = (JWLandscape*)[landcapeDrawable entity];
		
		[landscape deselectAllSquares];
		// We're interested in the named item closest to camera.
		
		GLuint name = 0;
		GLuint leastZ = UINT_MAX;
		while(hits--) {			
			if(pickBuffer[hits * 4 + 1] < leastZ) {					
				leastZ = pickBuffer[hits * 4 + 1];
				name = pickBuffer[hits * 4 + 3];
			}
		}
		
		GLuint maskedName = name & 0xFFFFFF;
		if(maskedName >= SQUARE_SELECTION_OFFSET && maskedName < TREE_SELECTION_OFFSET) {
			selectedItem = [[landscape landscape] objectAtIndex:maskedName - SQUARE_SELECTION_OFFSET];
			[selectedItem setSelected:YES];
		} else if(maskedName >= TREE_SELECTION_OFFSET && maskedName < BOX_SELECTION_OFFSET) {
			JWSquare* treeSquare = [[landscape landscape] objectAtIndex:maskedName - TREE_SELECTION_OFFSET];
			
			BOOL foundTree = NO;
			JWTreeDrawable* treeDrawable = (JWTreeDrawable*)[[JWDrawables sharedManager] drawableWithName:@"trees"];
			for(JWTree* tree in [treeDrawable treeList]) {
				
				[tree setSelected:NO];
				if([tree square] == treeSquare) {
					foundTree = YES;
					selectedItem = tree;
					[tree setSelected:YES];
				}
			}
			assert(foundTree);
			
		} else if(maskedName >= BOX_SELECTION_OFFSET && maskedName < ROBOT_SELECTION_OFFSET) {
			
			BOOL foundBox = NO;
			JWSquare* boxSquare = [[landscape landscape] objectAtIndex:maskedName - BOX_SELECTION_OFFSET];
			NSInteger boxHeight = name >> 24;
			
			JWBoxDrawable* boxDrawable = (JWBoxDrawable*)[[JWDrawables sharedManager] drawableWithName:@"boxes"];
			for(JWBox* box in [boxDrawable boxList]) {
				if([box square] == boxSquare && [box heightAboveSquare] == boxHeight) {
					foundBox = YES;
					selectedItem = box;
					[box setSelected:YES];
				}
			}
			assert(foundBox);
		} else if(maskedName >= ROBOT_SELECTION_OFFSET) {
			JWSquare* robotSquare = [[landscape landscape] objectAtIndex:maskedName - ROBOT_SELECTION_OFFSET];
			BOOL foundRobot = NO;
			JWRobotDrawable* robotDrawable = (JWRobotDrawable*)[[JWDrawables sharedManager] drawableWithName:@"robots"];
			for(JWRobot* robot in (NSArray*)[robotDrawable entity]) {
			
				[robot setSelected:NO];
				if([robot square] == robotSquare) {
					foundRobot = YES;
					selectedItem = robot;
					[robot setSelected:YES];
				}
			}
			assert(foundRobot);
		}
		
		NSNotification* notify = [NSNotification notificationWithName:@"net.weatherley.glSelection" object:selectedItem];
		[[NSNotificationCenter defaultCenter] postNotification:notify];
	}
}
*/
@end
